<?php

/**
 * Descripción Corta
 *
 * Descripción Larga.....
 *
 *
 * Desarrollado por la Escuela de Ingeniería de Antioquia
 *
 *
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       miBusWeb.Model
 * @fecha         Fecha Creación(yyyy-mm-dd)
 * @fecha_mod	  Fecha Modifiación
 * @cake		  CakePHP(tm) v 0.10.0.0
 */
App::uses('AppModel', 'Model');

class RecorridoRealizado extends AppModel {

    /**
     * Nombre de la tabla en base de datos
     *
     * Tabla relacionada con el modelo en cuestión, este atributo será usado para la generación
     * de consultas a la base de datos
     *
     * @var string
     */
    public $useTable = "recorridos_realizados";

    /**
     * Clave primaria de la tabla en base de datos
     *
     * Clave primaria que identifica cada registro de la tabla en cuestión
     *
     * @var string
     */
    public $primaryKey = "id_recorrido_realizado";

    /**
     * Campo de la tabla a usar como etiqueta/descripción
     *
     * Nombre del campo que se mostrara cuando se hacen busquedas del modelo mediante el método finde('list')
     *
     * @var string
     */
    public $displayField = "fecha_salida";

    /**
     * Nivel de recusividad para la busqueda de entidades relacionadas
     *
     * Este campo sirve para indicar si una consulta debe incluir las entidades
     * relacionadas con el modelo en cuestión:
     * 	-1	->	Solo información de tabla
     * 	0	->	Información de tabla y de belongsTo
     * 	1	->	Información de tabla, de belongsTo y de hasOne-hasMany
     * 	2	->	Información de tabla, de belongsTo, hasOne-hasMany y hasOne-hasMany de los relacionados
     *
     * @var int
     */
    public $recursive = 0;

    /**
     * Nombre del modelo
     *
     * Nombre del modelo que especifica como referirse a el en las consultas, busquedas, ingresos y
     * otras interacciones con la base de datos.
     *
     * @var string
     */
    public $name = "RecorridoRealizado";

    /**
     * Orden por defecto
     *
     * Orden por defecto para las consultas que se realicen a la base de datos,
     * se pueden incluir varios campos de la base de datos. Si se especifica
     * otro orden, este no se tiene en cuenta.
     *
     * @var array(string)
     */
    public $order = array("RecorridoRealizado.fecha_salida", "RecorridoRealizado.estado_recorrido_realizado");

    /**
     * Relaciones uno a muchos existentes del modelo
     */
    public $hasMany = array(
        "RecorridoRealizadoEvento" => array(
            "className" => "RecorridoRealizadoEvento",
            "foreignKey" => "id_recorrido_realizado",
        ),
        "RecorridoRealizadoParada" => array(
            "className" => "RecorridoRealizadoParada",
            "foreignKey" => "id_recorrido_realizado",
        ),
        "RecorridoRealizadoUsuarioParada" => array(
            "className" => "RecorridoRealizadoUsuarioParada",
            "foreignKey" => "id_recorrido_realizado",
        ),
        "RecorridoRealizadoReserva" => array(
            "className" => "Reserva",
            "foreignKey" => "id_recorrido_realizado",
        ),
    );

    /**
     * Relaciones muchos a uno existentes del modelo
     */
    public $belongsTo = array(
        "Bus" => array(
            "className" => "Bus",
            "foreignKey" => "id_bus",
        ),
        "Conductor" => array(
            "className" => "Conductor",
            "foreignKey" => "id_conductor",
        ),
        "Recorrido" => array(
            "className" => "Recorrido",
            "foreignKey" => "id_recorrido",
        ),
        "ProximaParada" => array(
            "className" => "Parada",
            "foreignKey" => "id_proxima_parada",
        ),
    );

    /**
     * Validaciones de cada uno de los atributos del modelo
     */
    public $validate = array(
        "id_recorrido_realizado" => array(
            "notEmpty" => array(
                "rule" => "notEmpty",
                "allowEmpty" => false,
                "required" => "update",
                "message" => "Id del recorrido realizado no puede estar vacio",
            ),
            "naturalNumber_NoZero" => array(
                "rule" => array("naturalNumber", false),
                "message" => "Id del recorrido realizado debe ser un número entero diferente de cero",
            ),
            "isUnique" => array(
                "rule" => array("isUnique"),
                "message" => "Id del recorrido realizado debe ser único",
            ),
        ),
        "id_bus" => array(
            "notEmpty" => array(
                "rule" => "notEmpty",
                "allowEmpty" => false,
                "required" => true,
                "message" => "Id del bus no puede estar vacio",
            ),
            "naturalNumber_NoZero" => array(
                "rule" => array("naturalNumber", false),
                "message" => "Id del bus debe ser un número entero diferente de cero",
            ),
        ),
        "id_conductor" => array(
            "notEmpty" => array(
                "rule" => "notEmpty",
                "allowEmpty" => false,
                "required" => true,
                "message" => "Id del conductor no puede estar vacio",
            ),
            "naturalNumber_NoZero" => array(
                "rule" => array("naturalNumber", false),
                "message" => "Id del conductor debe ser un número entero diferente de cero",
            ),
        ),
        "id_recorrido" => array(
            "notEmpty" => array(
                "rule" => "notEmpty",
                "allowEmpty" => false,
                "required" => true,
                "message" => "Id del recorrido no puede estar vacio",
            ),
            "naturalNumber_NoZero" => array(
                "rule" => array("naturalNumber", false),
                "message" => "Id del recorrido debe ser un número entero diferente de cero",
            ),
        ),
        "fecha_salida" => array(
            "notEmpty" => array(
                "rule" => "notEmpty",
                "allowEmpty" => false,
                "required" => "create",
                "message" => "Fecha de salida del recorrido realizado no puede estar vacio",
            ),
            "date" => array(
                "rule" => array("datetime"),
                "message" => "Fecha de salida del recorrido realizado debe tener formato yyyy/mm/dd",
            ),
        ),
        "fecha_llegada" => array(
            "date" => array(
                "rule" => array("datetime"),
                "allowEmpty" => true,
                "required" => false,
                "message" => "Fecha de llegada del recorrido realizado debe tener formato yyyy/mm/dd hh:mm",
            ),
        ),
        "estado_recorrido_realizado" => array(
            "notEmpty" => array(
                "rule" => "notEmpty",
                "allowEmpty" => false,
                "required" => true,
                "message" => "Estado del recorrido realizado no puede estar vacio",
            ),
            "inList" => array(
                "rule" => array("inList", array('movimiento', 'detenido', 'evento', 'finalizado', 'programado')),
                "message" => "Estado del recorrido realizado debe ser 'movimiento', 'detenido', 'evento' o 'finalizado'",
            ),
        ),
        'latitud' => array(
            'numeric-2' => array(
                'rule' => 'numeric',
                "allowEmpty" => true,
                "required" => false,
                'message' => 'la latitud del recorrido realizado debe ser un número'
            ),
            'range-3' => array(
                'rule' => array('range', -90, 90),
                'message' => 'la latitud del recorrido realizado debe ser un número entre -90 y 90'
            )
        ),
        'longitud' => array(
            'numeric-2' => array(
                'rule' => 'numeric',
                "allowEmpty" => true,
                "required" => false,
                'message' => 'la longitud del recorrido realizado debe ser un número'
            ),
            'range-3' => array(
                'rule' => array('range', -180, 180),
                'message' => 'la longitud del recorrido realizado debe ser un número entre -180 y 180'
            )
        ),
        'velocidad_promedio' => array(
            'numeric-2' => array(
                'rule' => 'numeric',
                "allowEmpty" => false,
                "required" => true,
                'message' => 'la velocidad promedio del recorrido realizado debe ser un número'
            )
        ),
        'puestos_ocupados' => array(
            "naturalNumber_Zero" => array(
                "rule" => array("naturalNumber", true),
                "allowEmpty" => false,
                "required" => true,
                "message" => "Los puestos ocupados del recorrido realizado deben ser un número entero",
            ),
        ),
        'puestos_reservados' => array(
            "naturalNumber_Zero" => array(
                "rule" => array("naturalNumber", true),
                "allowEmpty" => false,
                "required" => true,
                "message" => "Los puestos reservados del recorrido realizado deben ser un número entero",
            ),
        ),
        'contador_inactividad' => array(
            "naturalNumber_Zero" => array(
                "rule" => array("naturalNumber", true),
                "allowEmpty" => false,
                "required" => true,
                "message" => "El contador de inactividad del recorrido realizado deben ser un número entero",
            ),
        ),
        "fecha_actualizacion_recorrido" => array(
            "date" => array(
                "rule" => array("datetime"),
                "allowEmpty" => true,
                "required" => false,
                "message" => "Fecha de actualizacion del recorrido realizado debe tener formato yyyy/mm/dd hh:mm",
            ),
        ),
    );

    /**
     * 				DATA VALIDATION METHODS
     */

    /**
     * 				MODEL CALLBACKS METHODS
     */

    // public function beforeFind(array $queryData) {
    // }
    // public function afterFind(array $results, boolean $primary = false) {
    // }
    // public function beforeValidate(array $options = array()) {
    // }

    public function beforeSave($options = array()) {
        if (isset($this->data[$this->name]['fecha_llegada']) && (empty($this->data[$this->name]['fecha_llegada']) || strlen(trim($this->data[$this->name]['fecha_llegada'])) === 0)) {
            unset($this->data[$this->name]['fecha_llegada']);
        }
        return true;
    }

    // public function afterSave(boolean $created) {
    // }
    // public function beforeDelete(boolean $cascade = true) {
    // }
    // public function afterDelete() {
    // }

    /**
     * 				MODEL METHODS
     */

    /**
     * Descripcion corta metodo.
     *
     * Descripción larga metodo
     *
     * @param array() $data parametro que sirve para..
     * @param boolean $validate parametro que sirve para..
     * @param boolean $fieldList parametro que sirve para..
     * @return boolean true en caso de exito, false en otro caso
     */
    public function save($data = null, $validate = true, $isMobile = false, $fieldList = array()) {
        $this->set($data);

        if (!isset($data["RecorridoRealizado"]['fecha_salida'])) {
            $this->set(array(
                'fecha_salida' => date('Y/m/j H:i:s'),
            ));
        }
        if (!isset($data["RecorridoRealizado"]['estado_recorrido_realizado'])) {
            $this->set(array(
                'estado_recorrido_realizado' => "movimiento",
            ));
        }
        if (!isset($data["RecorridoRealizado"]['contador_inactividad'])) {
            $this->set(array(
                'contador_inactividad' => 0,
            ));
        }

        if ($validate) {
            $this->Bus->set('id_bus', $data['Bus']['id_bus']);
            if ($this->Bus->validates(array('fieldList' => array('id_bus')))) {
                $this->set(array(
                    "id_bus" => $data['Bus']['id_bus']
                ));
            }

            $this->Conductor->set('id_conductor', $data['Conductor']['id_conductor']);
            if ($this->Conductor->validates(array('fieldList' => array('id_conductor')))) {
                $this->set(array(
                    "id_conductor" => $data['Conductor']['id_conductor']
                ));
            }

            $this->Recorrido->set('id_recorrido', $data['Recorrido']['id_recorrido']);
            if ($this->Recorrido->validates(array('fieldList' => array('id_recorrido')))) {
                $this->set(array(
                    "id_recorrido" => $data['Recorrido']['id_recorrido']
                ));
            }

            if ($this->validates()) {
                return parent::save($this->data, false, $fieldList);
            } else {
                return false;
            }
        } else {
            if (!$isMobile) {             //Esta verificacion la puse para el post de android
                $this->set(array(
                    "id_bus" => $data['Bus']['id_bus'],
                    "id_conductor" => $data['Conductor']['id_conductor'],
                    "id_recorrido" => $data['Recorrido']['id_recorrido'],
                ));
            }

            return parent::save($this->data, $validate, $fieldList);
        }
    }

    /**
     * Descripcion corta metodo.
     *
     * Descripción larga metodo
     *
     * @param int $id parametro que sirve para..
     * @param boolean $cascade parametro que sirve para..
     * @return boolean true en caso de exito, false en otro caso
     */
    public function delete($id = null, $cascade = true) {
        $recorridorealizado = $this->find('first', array(
            'conditions' => array('RecorridoRealizado.id_recorrido_realizado' => $id),
            'recursive' => 1,
        ));

        $hasChilds = false;
        foreach ($recorridorealizado as $child_model => $i) {
            if (($child_model == "RecorridoRealizadoEvento" || $child_model == "Reserva" || $child_model == "RecorridoRealizadoParada" || $child_model == "RecorridoRealizadoUsuarioParada" ) && sizeof($recorridorealizado[$child_model]) != 0) {
                $hasChilds = true;
                break;
            }
        }

        if (!$hasChilds) {
            return parent::delete($id, $cascade);
        } else {
            $recorridorealizado["RecorridoRealizado"]["estado_recorrido_realizado"] = "finalizado";
            return $this->save($recorridorealizado);
        }
    }

    /**
     * Descripcion corta metodo.
     *
     * Descripción larga metodo
     *
     * @param int $id parametro que sirve para..
     * @param boolean $cascade parametro que sirve para..
     * @return boolean true en caso de exito, false en otro caso
     */
    public function findNoFinalizadosAndNoProgramados() {
        return $this->find('all', array(
                    'conditions' => array('RecorridoRealizado.estado_recorrido_realizado !=' => array('finalizado', 'programado')),
        ));
    }

    public function findAll($start = null, $length = null, $order = array(), $filter = array(), $conditions = array(), $contain = array()) {
        $contain = array(
            'Bus',
            'Conductor'
        );
        return parent::findAll($start, $length, $order, $filter, $conditions, $contain);
    }

    public function findCountAll($filter = array(), $conditions = array(), $contain = array()) {
        $contain = array(
            'Bus',
            'Conductor'
        );
        return parent::findCountAll($filter, $conditions, $contain);
    }

}
